<?php


namespace app\controller\api;


use app\common\service\sms\AliSms;
use app\common\service\wxapi\MiniProgram;
use app\common\service\wxapi\WxBizDataCrypt;
use app\model\AdminStaff;
use app\model\AdminUser;
use app\model\AdminVisitRegistrationLog;
use app\model\AdminVisitUser;
use app\util\ReturnCode;
use think\facade\Cache;
use think\facade\Log;
use think\facade\Validate;
use think\Response;

class WxPassport extends Base
{
    // 管理员/门卫登录
    public function loginByPhone() : Response
    {
        $api_auth = $this->request->header('Api-Auth');
        $params['type'] = $this->request->post('type', 'admin');
        // login_type类型 phone_captcha 手机验证码 wechat_phone 微信授权登录
        $params['login_type'] = $this->request->post('login_type');
        $params['mobile'] = $this->request->post('mobile');
        $params['captcha'] = $this->request->post('captcha');
        $params['encryptedData'] = $this->request->post('encryptedData');
        $params['iv'] = $this->request->post('iv');
        $code = $this->request->post('code', '');

        $validate = Validate::rule([
            'login_type|登录类型'=>'require|in:phone_captcha,wechat_phone',
            'mobile|手机号'=>'requireIf:login_type,phone_captcha|mobile',
            'captcha|验证码' => 'requireIf:login_type,phone_captcha',
            'encryptedData' => 'requireIf:login_type,wechat_phone',
            'iv' => 'requireIf:login_type,wechat_phone',
            'type|类型' => 'require|in:admin,worker',
        ]);
        if (!$validate->check($params)) {
            return $this->buildFailed(ReturnCode::PARAM_INVALID, $validate->getError());
        }

        //验证码登录
        if ($params['login_type'] == 'phone_captcha') {
            if (!AliSms::check($params['mobile'], intval($params['captcha']))) {
                return $this->buildFailed(ReturnCode::RECORD_NOT_FOUND, '验证码错误');
            }
        } else {
            //微信授权手机登录
            try {
                $service = new MiniProgram();
                $session_key = '';
                if (!$code && $api_auth){
                    $session_key = Cache::get('wx_login_api' .$api_auth) ? Cache::get('wx_login_api' .$api_auth) : $session_key;
                } else {
                    [
                        'session_key' => $session_key,
                        'openid' => $openid,
                    ] = $service->code2Openid($code);
                }
                if (!$session_key){
                    return $this->buildFailed(ReturnCode::LOGIN_ERROR, '请重新授权登录');
                }

                $data = $service->decryptData($session_key, $params['iv'], $params['encryptedData']);
            }catch (\Exception $exception){
                return $this->buildFailed(ReturnCode::LOGIN_ERROR, '微信手机授权失败：' . $exception->getMessage());
            }

            if ($data && isset($data['purePhoneNumber'])) {
                $params['mobile'] = $data && $data['purePhoneNumber'] ? $data['purePhoneNumber'] : '';
            }else{
                return $this->buildFailed(ReturnCode::LOGIN_ERROR, '微信手机授权失败，请尝试重新授权登录');
            }
        }

        //验证手机用户
        if ($params['type'] == 'worker') {
            $user = (new AdminStaff())->where(['phone' => $params['mobile'], 'is_delete' => 0, 'status' => 1])->find();
            $permission = $user->permission;
            $query_permission = isset($permission['query']);
            if (!$query_permission) {
                return $this->buildFailed(ReturnCode::AUTH_ERROR, '权限不足，登录失败，请联系管理员');
            }
        } else {
            $user = (new AdminUser())->where(['phone' => $params['mobile'], 'status' => 1])->find();
        }
        if ($user) {
            if (!$user->wx_api_token) {
                //存储用户登录状态
                $apiAuth = md5(uniqid() . time());
                $user->wx_api_token = $apiAuth;
                if (!$user->save()){
                    return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '用户登录失败');
                }
            }
            if ($params['login_type'] == 'wechat_phone' && $session_key){
                Cache::set('wx_login_api' .$user->wx_api_token , $session_key, 60 * 60 * 24 * 3);
            }

            $userInfo = $user->toArray();
            $userInfo['apiAuth'] = $userInfo['wx_api_token'];
            unset($userInfo['wx_api_token']);
            unset($userInfo['password']);
            return $this->buildSuccess($userInfo, '登录成功');
        } else {
            return $this->buildFailed(ReturnCode::DATA_EXISTS, '用户不存在/用户被封禁');
        }
    }

    // 来访登记静默登录
    public function loginByVisit(): Response
    {
        $code = $this->request->get('code');
        $apiAuth = $this->request->header('Api-Auth');
        if (!$code && !$apiAuth) {
            return $this->buildFailed(ReturnCode::PARAM_INVALID, '缺少参数');
        }
        //微信静默登录
        $service = new MiniProgram();
        $openid = '';
        if ($code) {
            [
                'session_key' => $session_key,
                'openid' => $openid,
            ] = $service->code2Openid($code);
        }

        $user = (new AdminVisitUser())->where(['openid' => $openid, 'is_delete' => 0])->find();
        if (!$user){
            $user = new AdminVisitUser();
            $wx_api_token = md5(uniqid() . time());
            $data = [
                'openid' => $openid,
                'wx_api_token' => $wx_api_token,
                'create_time' => time(),
                'update_time' => time(),
            ];
            $res = $user->save($data);
            if (!$res) {
                return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '用户登录失败');
            }
        }

        //来访用户最新数据
        $log = (new AdminVisitRegistrationLog())->where(['user_id' => $user->id, 'is_delete' => 0])->order('create_time DESC, id ASC')->find();

        $userInfo['log_id'] = $log ? $log->id : '';
        $userInfo['apiAuth'] = $user->wx_api_token;
        return $this->buildSuccess($userInfo, '登录成功');
    }
}